#!/bin/bash
# https://prometheus.io/download/
# https://github.com/prometheus/prometheus/releases/download/v2.53.1/prometheus-2.53.1.linux-amd64.tar.gz
# https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
# https://github.com/prometheus/pushgateway/releases/download/v1.9.0/pushgateway-1.9.0.linux-amd64.tar.gz

set -euo pipefail

#****** vars ******#
# true or false
INSTALL_PROMETHEUS_FLAG=true
INSTALL_ALERTMANAGER_FLAG=true
INSTALL_PUSHGATEWAY_FLAG=true
INSTALL_NODE_EXPORTER_FLAG=true
INSTALL_BLACKBOX_EXPORTER_FLAG=true
# prometheus vars
PROMETHEUS_VERSION="2.53.1"
PROMETHEUS_USER="prometheus"
PROMETHEUS_INSTALL_PATH="/usr/local"
PROMETHEUS_DATA_PATH="/data/prometheus"

# alertmanager vars
ALERTMANAGER_VERSION="0.27.0"
ALERTMANAGER_USER="prometheus"
ALERTMANAGER_INSTALL_PATH="/usr/local"

# pushgateway vars
PUSHGATEWAY_VERSION="1.9.0"
PUSHGATEWAY_USER="prometheus"
PUSHGATEWAY_INSTALL_PATH="/usr/local"

# node_exporter vars
NODE_EXPORTER_VERSION="1.8.2"
NODE_EXPORTER_USER="prometheus"
NODE_EXPORTER_INSTALL_PATH="/usr/local"

# blackbox_exporter vars
BLACKBOX_EXPORTER_VERSION="0.25.0"
BLACKBOX_EXPORTER_USER="prometheus"
BLACKBOX_EXPORTER_INSTALL_PATH="/usr/local"
#****** functions ******#

color() {
    local message="$1"
    local status="$2"
    local terminal_width
    terminal_width=$(tput cols)
    local middle_column=$(( terminal_width / 2))
    local SETCOLOR_SUCCESS="\033[1;32m"  # 绿色
    local SETCOLOR_FAILURE="\033[1;31m"  # 红色
    local SETCOLOR_WARNING="\033[1;33m"  # 黄色
    local SETCOLOR_NORMAL="\033[0m"      # 重置颜色
    printf '%s\n\033[%sG' "${message}"  "${middle_column}"
    # Print the status message
    printf "["
    case ${status} in
        success|0)
            echo -en  "${SETCOLOR_SUCCESS}  OK  "
            ;;
        failure|1)
            echo -en  "${SETCOLOR_FAILURE}FAILED"
            ;;
        *)
            echo -en "${SETCOLOR_WARNING}WARNING"
            ;;
    esac
    echo -e "${SETCOLOR_NORMAL}]"
}

create_user () {
    if ! id "$1" &> /dev/null;then
        useradd -r -M -s /sbin/nologin "$1" \
        && color "$1 user is created." 0 \
        || { color "$1 user create failed.";exit; }
    else
        color "$1 user is existed." 2
    fi
}

create_dir () {
    local i
    for i in "$@";do
        if [ ! -d "$i" ];then
            mkdir -pv "$i" && color "$i dir is created" 0
        else
            color "$i dir is existed." 2
        fi
    done
}

judge_current_user () {
    if [ "$(id -u)" = "0" ];then
        color "current user is administrator" 0
    else
        color "current user is not administrator" 1
        exit
    fi
}

judge_true_false () { # $1 is var, $2 is function
    if ! [[ $1 =~ ^true|false$ ]];then
        color "$1 value is not true or false,check your vars set." 1
        exit
    elif [ "$1" = true ];then
        $2
    fi
}

judge_file_exist () { 
    local i=0
    for i in "$@";do
        if [ -e "$i" ];then
            color "current dir $i exist." 0
        else
            color "current dir don't exist $i" 1
            exit
        fi
    done
}

install_prometheus () {
    judge_file_exist prometheus-${PROMETHEUS_VERSION}.linux-amd64.tar.gz
    create_user ${PROMETHEUS_USER}
    create_dir ${PROMETHEUS_INSTALL_PATH} ${PROMETHEUS_DATA_PATH}

    tar -xvf prometheus-${PROMETHEUS_VERSION}.linux-amd64.tar.gz -C ${PROMETHEUS_INSTALL_PATH}
    ln -nfs ${PROMETHEUS_INSTALL_PATH}/prometheus-${PROMETHEUS_VERSION}.linux-amd64 ${PROMETHEUS_INSTALL_PATH}/prometheus
    chown -R ${PROMETHEUS_USER}:${PROMETHEUS_USER} ${PROMETHEUS_INSTALL_PATH}/prometheus-${PROMETHEUS_VERSION}.linux-amd64 ${PROMETHEUS_DATA_PATH}

    cat > /lib/systemd/system/prometheus.service<<EOF
[Unit]
Description=Prometheus Server,Monitoring system and time series database
Documentation=https://prometheus.io/docs/introduction/overview/
After=time-sync.target network.target

[Service]
Restart=on-failure
User=${PROMETHEUS_USER}
Group=${PROMETHEUS_USER}
ExecStartPre=${PROMETHEUS_INSTALL_PATH}/prometheus/promtool check config ${PROMETHEUS_INSTALL_PATH}/prometheus/prometheus.yml
ExecStart=${PROMETHEUS_INSTALL_PATH}/prometheus/prometheus --storage.tsdb.path=${PROMETHEUS_DATA_PATH} --config.file=${PROMETHEUS_INSTALL_PATH}/prometheus/prometheus.yml
ExecReload=${PROMETHEUS_INSTALL_PATH}/prometheus/promtool check config ${PROMETHEUS_INSTALL_PATH}/prometheus/prometheus.yml
ExecReload=/bin/kill -HUP \$MAINPID
TimeoutStopSec=20s
SendSIGKILL=no

# systemd hardening-options
AmbientCapabilities=
CapabilityBoundingSet=
DeviceAllow=/dev/null rw
DevicePolicy=strict
LimitMEMLOCK=0
LimitNOFILE=65535
LockPersonality=true
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
PrivateTmp=true
PrivateUsers=true
ProtectControlGroups=true
ProtectHome=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectSystem=full
RemoveIPC=true
RestrictNamespaces=true
RestrictRealtime=true
SystemCallArchitectures=native

[Install]
WantedBy=multi-user.target
EOF
    systemctl daemon-reload
    systemctl enable prometheus.service
    systemctl start prometheus.service \
    && color "prometheus.service start sucess!" 0 \
    || { color "prometheus.service  start fail." 1; exit; }
}

install_alertmanager () {
    judge_file_exist alertmanager-${ALERTMANAGER_VERSION}.linux-amd64.tar.gz
    create_user ${ALERTMANAGER_USER}
    create_dir ${ALERTMANAGER_INSTALL_PATH}
    tar -xvf alertmanager-${ALERTMANAGER_VERSION}.linux-amd64.tar.gz -C ${ALERTMANAGER_INSTALL_PATH}
    ln -nfs ${ALERTMANAGER_INSTALL_PATH}/alertmanager-${ALERTMANAGER_VERSION}.linux-amd64 ${ALERTMANAGER_INSTALL_PATH}/alertmanager
    chown -R ${ALERTMANAGER_USER}:${ALERTMANAGER_USER} ${ALERTMANAGER_INSTALL_PATH}/alertmanager-${ALERTMANAGER_VERSION}.linux-amd64
    cat > /lib/systemd/system/alertmanager.service<<EOF
[Unit]
Description=The Alertmanager handles alerts sent by client applications such as the Prometheus server
Documentation=https://prometheus.io/docs/alerting/latest/alertmanager/
After=time-sync.target network.target
[Service]
Restart=on-failure
User=${ALERTMANAGER_USER}
Group=${ALERTMANAGER_USER}
ExecStartPre=${ALERTMANAGER_INSTALL_PATH}/alertmanager/amtool check-config ${ALERTMANAGER_INSTALL_PATH}/alertmanager/alertmanager.yml
ExecStart=${ALERTMANAGER_INSTALL_PATH}/alertmanager/alertmanager --config.file=${ALERTMANAGER_INSTALL_PATH}/alertmanager/alertmanager.yml
ExecReload=${ALERTMANAGER_INSTALL_PATH}/alertmanager/amtool check-config ${ALERTMANAGER_INSTALL_PATH}/alertmanager/alertmanager.yml
ExecReload=/bin/kill -HUP \$MAINPID
TimeoutStopSec=20s
SendSIGKILL=no

# systemd hardening-options
AmbientCapabilities=
CapabilityBoundingSet=
DeviceAllow=/dev/null rw
DevicePolicy=strict
LimitMEMLOCK=0
LimitNOFILE=65535
LockPersonality=true
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
PrivateTmp=true
PrivateUsers=true
ProtectControlGroups=true
ProtectHome=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectSystem=full
RemoveIPC=true
RestrictNamespaces=true
RestrictRealtime=true
SystemCallArchitectures=native

[Install]
WantedBy=multi-user.target
EOF
    systemctl daemon-reload
    systemctl enable alertmanager.service
    systemctl start alertmanager.service \
    && color "alertmanager.service start sucess!" 0 \
    || { color "alertmanager.service  start fail." 1; exit; }
}

install_pushgateway () {
    judge_file_exist pushgateway-${PUSHGATEWAY_VERSION}.linux-amd64.tar.gz
    create_user ${PUSHGATEWAY_USER}
    create_dir ${PUSHGATEWAY_INSTALL_PATH}
    tar -xvf pushgateway-${PUSHGATEWAY_VERSION}.linux-amd64.tar.gz -C ${PUSHGATEWAY_INSTALL_PATH}
    ln -nfs ${PUSHGATEWAY_INSTALL_PATH}/pushgateway-${PUSHGATEWAY_VERSION}.linux-amd64 ${PUSHGATEWAY_INSTALL_PATH}/pushgateway
    chown -R ${PUSHGATEWAY_USER}:${PUSHGATEWAY_USER} ${PUSHGATEWAY_INSTALL_PATH}/pushgateway-${PUSHGATEWAY_VERSION}.linux-amd64

    cat > /lib/systemd/system/pushgateway.service <<EOF
[Unit]
Description=Prometheus Pushgateway
After=time-sync.target network.target

[Service]
Type=simple
ExecStart=${PUSHGATEWAY_INSTALL_PATH}/pushgateway/pushgateway
ExecReload=/bin/kill -HUP \$MAINPID
Restart=on-failure
User=prometheus
Group=prometheus


[Install]
WantedBy=multi-user.target
EOF
    systemctl daemon-reload
    systemctl enable pushgateway.service
    systemctl start pushgateway.service \
    && color "pushgateway.service start sucess!" 0 \
    || { color "pushgateway.service  start fail." 1; exit; }
}

install_node_exporter () {
    judge_file_exist node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz
    create_user ${NODE_EXPORTER_USER}
    create_dir ${NODE_EXPORTER_INSTALL_PATH}
    tar -xvf node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz -C ${NODE_EXPORTER_INSTALL_PATH}
    ln -nfs ${NODE_EXPORTER_INSTALL_PATH}/node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64 ${NODE_EXPORTER_INSTALL_PATH}/node_exporter
    chown -R ${NODE_EXPORTER_USER}:${NODE_EXPORTER_USER} ${NODE_EXPORTER_INSTALL_PATH}/node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64

    cat >/lib/systemd/system/node_exporter.service <<EOF
[Unit]
Description=Prometheus exporter for machine metrics
Documentation=https://github.com/prometheus/node_exporter

[Service]
Restart=on-failure
User=${NODE_EXPORTER_USER}
ExecStart=${NODE_EXPORTER_INSTALL_PATH}/node_exporter/node_exporter
ExecReload=/bin/kill -HUP \$MAINPID
TimeoutStopSec=20s
SendSIGKILL=no

[Install]
WantedBy=multi-user.target
EOF
    systemctl daemon-reload
    systemctl enable node_exporter.service
    systemctl start node_exporter.service \
    && color "node_exporter.service start sucess!" 0 \
    || { color "node_exporter.service  start fail." 1; exit; }
}

install_blackbox_exporter () {
    judge_file_exist blackbox_exporter-${BLACKBOX_EXPORTER_VERSION}.linux-amd64.tar.gz
    create_user ${BLACKBOX_EXPORTER_USER}
    create_dir ${BLACKBOX_EXPORTER_INSTALL_PATH}
    tar -xvf blackbox_exporter-${BLACKBOX_EXPORTER_VERSION}.linux-amd64.tar.gz -C ${BLACKBOX_EXPORTER_INSTALL_PATH}
    ln -nfs ${BLACKBOX_EXPORTER_INSTALL_PATH}/blackbox_exporter-${BLACKBOX_EXPORTER_VERSION}.linux-amd64 ${BLACKBOX_EXPORTER_INSTALL_PATH}/blackbox_exporter
    chown -R ${BLACKBOX_EXPORTER_USER}:${BLACKBOX_EXPORTER_USER} ${BLACKBOX_EXPORTER_INSTALL_PATH}/blackbox_exporter-${BLACKBOX_EXPORTER_VERSION}.linux-amd64

    cat >/lib/systemd/system/blackbox_exporter.service <<EOF
[Unit]
Description=Prometheus exporter for Blackbox
Documentation=https://github.com/prometheus/blackbox_exporter

[Service]
Restart=on-failure
User=${BLACKBOX_EXPORTER_USER}
ExecStart=${BLACKBOX_EXPORTER_INSTALL_PATH}/blackbox_exporter/blackbox_exporter --config.file=${BLACKBOX_EXPORTER_INSTALL_PATH}/blackbox_exporter/blackbox.yml --web.listen-address=:9115
ExecReload=/bin/kill -HUP \$MAINPID
LimitNOFILE=100000
TimeoutStopSec=20s
SendSIGKILL=no

[Install]
WantedBy=multi-user.target
EOF
    systemctl daemon-reload
    systemctl enable blackbox_exporter.service
    systemctl start blackbox_exporter.service \
    && color "blackbox_exporter.service start sucess!" 0 \
    || { color "blackbox_exporter.service  start fail." 1; exit; }
}

main () {
    judge_current_user
    judge_true_false $INSTALL_PROMETHEUS_FLAG    install_prometheus
    judge_true_false $INSTALL_ALERTMANAGER_FLAG  install_alertmanager
    judge_true_false $INSTALL_PUSHGATEWAY_FLAG   install_pushgateway
    judge_true_false $INSTALL_NODE_EXPORTER_FLAG install_node_exporter
    judge_true_false $INSTALL_BLACKBOX_EXPORTER_FLAG install_blackbox_exporter
}

main
